const chalk = require('chalk')
const defconfig = require('../config');
const axios = require('axios');
const path = require('path');
const fs = require('fs-extra');
const _ = require('lodash');
async function fetchRemoteOpenApi(url) {
  try {
    // 使用 axios 发起 GET 请求
    const response = await axios.get(url);
    // response.data 包含了请求返回的数据，即 OpenAPI 文件内容
    return response.data;
  } catch (error) {
    // 错误处理
    console.error('读取远程 OpenAPI 文件时出错');
    throw error;
  }
}
function extractPathParams(urlTemplate) {
  const regex = /{([^}]+)}/g;
  const params = [];
  let match;
  
  while ((match = regex.exec(urlTemplate)) !== null) {
    params.push(match[1]);
  }
  
  return params;
}

function parsePathUrl(url) {
   // 用于找到第一个路径参数的正则表达式
   const URL_SPLIT_REGEX = /^(.*?)(\/{[^/]+})(.*)$/;

   // 用正则表达式进行匹配
   const match = URL_SPLIT_REGEX.exec(url);
   
   if (match) {
     // 如果匹配到，返回两部分路径
     const [_, beforeParams, firstParam, afterFirstParam] = match;
     return {
       beforeFirstParam: beforeParams,
       pathParams: firstParam + afterFirstParam
      };
   } else {
     // 如果没有路径参数，则返回原始 URL 和空字符串作为参数部分
     return {
       beforeFirstParam: url,
       pathParams: ''
     };
   }
}

 function parseUrl(str){

// 删除 '/jeecg-boot/' 子字符串
const modifiedStr = str.replace('/jeecg-boot/', '');

// 现在 modifiedStr 是 '路径/路径2/资源/方法'
// 可以使用 split 方法来获取路径、资源和方法
const parts = modifiedStr.split('/');

// 确定最后一个 '/' 的位置
const lastSlashIndex = modifiedStr.lastIndexOf('/');

// 根据最后一个 '/' 的位置来获取资源和方法
let resource, action, cpath;
if (lastSlashIndex === -1) {
  // 没有 '/'，整个字符串是资源和方法
  resource ='';
  action = parts[0]; // 如果没有方法，可以假设资源即方法
  cpath = ''; // 没有额外的路径
} else {
  // 有 '/'，最后一个元素是方法，倒数第二个元素是资源
  resource = parts.slice(-2, -1)[0];
  action = parts.slice(-1)[0];
  cpath = parts.slice(0, -2).join('/'); // 获取除了资源和方法之外的路径
}
return { resource, action, cpath };
// console.log('资源:', resource); // 输出: 资源
// console.log('方法:', action); // 输出: 方法
// console.log('路径:', cpath);   // 输出: 路径/路径2
 }





module.exports = async function createApi(str, options){
  try {
    const config = Object.assign({}, defconfig, str);
    if(!config.openapiUrl)return console.log(chalk.red.bold('openapi地址为空'));
    const data = await fetchRemoteOpenApi(config.openapiUrl)
    const savePath = path.join(process.cwd(), config.apiPath||'','method')
    // 按照路径合并接口项目
    const listObj={}
    for (const key in data.paths) {
      const {beforeFirstParam,pathParams} =parsePathUrl(key)
      const { resource, action, cpath } = parseUrl(beforeFirstParam,config.cutPath);
      const method=Object.keys(data.paths[key])
      const objkey = savePath+'::'+ path.join(cpath,resource)+'||'+action+'///'+pathParams
      // console.log(objkey)
      listObj[objkey]=listObj[objkey]||[]
      listObj[objkey]=[...new Set([...listObj[objkey], ...method])]
    }
    const lastList={}
    for (const key in listObj) {
      const [fullPath,action] = key.split('||')
      const method=listObj[key]
      lastList[fullPath] = lastList[fullPath]||{}
      lastList[fullPath][action]=method
    }
    //生成文件
    //清空文件夹
    await fs.remove(savePath);
    for (const key in lastList) {
      const [basePath,router] = key.split('::')
      // console.log(basePath,router)
      const fullPath = path.join(basePath,router+'.js');
      const apirouter = router.replace(/\\/g, '/')
      // console.log(fullPath)
      let fileContext=`import { fetch } from '@/utils/request';
`
      for (let action in lastList[key]) {
        const methods=lastList[key][action]
        for (const method of methods) {
    
          let Cmenthod= method.charAt(0).toUpperCase() + method.toLowerCase().slice(1)
          let [vaction,pathParams] = action.split('///')
          //驼峰名名
          cvaction =  _.startCase(_.camelCase(vaction)).replace(/ /g, '')
          let Caction = config.mutilMethod?cvaction+'_'+Cmenthod:cvaction;
          let keystr = ''
          if(pathParams){//存在路径参数
            const keys=extractPathParams(pathParams)
            keystr=keys.join(',')+','
            pathParams=pathParams.replace(/\{/g, '${')
          }
         if(['GET','HEAD','OPTIONS'].includes(method.toUpperCase())){
          fileContext+=`export const ${Caction} = (${keystr}data,config) => fetch.${Cmenthod}(\`/${apirouter}/${vaction}${pathParams}\`,Object.assign({ params: data},config));
`
        }else{
          fileContext+=`export const ${Caction} = (${keystr}data,config) => fetch.${Cmenthod}(\`/${apirouter}/${vaction}${pathParams}\`,data,config);
`
        }
          
          if(!config.mutilMethod) break
        }
      }
      await fs.outputFile(fullPath, fileContext)
    }
    console.log(chalk.green.bold('生成完成'));
  } catch (error) {
    console.log(chalk.red.bold('解析失败'),error);
  }
 
}